package fdts.data.io;

/********************************************************
 * FDTS SS 2012. Calendar Layouter and iCalendar Imorter*
 * ******************************************************/

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import timeBench.calendar.Calendar;
import timeBench.calendar.CalendarManager;
import timeBench.calendar.CalendarManagerFactory;
import timeBench.calendar.CalendarManagers;
import timeBench.calendar.Granularity;
import timeBench.calendar.JavaDateCalendarManager;

import fdts.calendar.layout.CalendarAxis;
import fdts.calendar.layout.CalendarAxisSpecification;

/**
 * this class read the xml definitions for the axis layout for each granularity.
 * 
 * @author agnieszka wojdecka and andreas hoermann
 *
 */
public class XMLAxesDefinitionReader{
	/**
	 * this method reads in a xml-file with the definition for the x-axis and y-axis of one 
	 * granularity view.
	 * 
	 * @param f a xml file with the definition of the granularity
	 * @return ArrayList<CalendarAxis> a list with two CalendarAxis, x- and y-axis. 
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 */
	public ArrayList<CalendarAxis> read(File f) throws ParserConfigurationException, SAXException, IOException{
		ArrayList<CalendarAxis> axes = new ArrayList<CalendarAxis>();
		
		CalendarManager manager = CalendarManagerFactory.getSingleton(CalendarManagers.JavaDate);
        Calendar calendar = manager.getDefaultCalendar();
        int identifier = -1;
		int contextIdentifier = -1;
		String type= "";
		int perpage = 0;
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(f);
		doc.getDocumentElement().normalize();
		
		if( doc.getDocumentElement().getNodeName().equals("axesDefinition") ){
			NodeList nodes = doc.getElementsByTagName("axis");
			for(int i = 0; i<nodes.getLength();i++){
				Node n = nodes.item(i);
				if( n.getNodeName().equals("axis")){
					String gr1 = n.getTextContent();
					identifier = getId(gr1);
					String gr2 = f.getName().substring(0,f.getName().lastIndexOf(".xml"));
					contextIdentifier = getId(gr2);
					Granularity granularity = new Granularity(calendar, identifier, contextIdentifier);
					
					NamedNodeMap map = n.getAttributes();
					for(int j=0; j<map.getLength();j++){
						if(map.item(j).getNodeName().equals("type"))
							type = map.item(j).getTextContent();
						else if(map.item(j).getNodeName().equals("perpage"))
							perpage = Integer.parseInt(map.item(j).getTextContent());
						else
							System.out.println( "Attribute not supported at the moment!" );
					}
					CalendarAxisSpecification specification = new CalendarAxisSpecification(type,perpage);
					
					axes.add(new CalendarAxis(granularity, specification));
				}
				
			}
		}
		 
		return axes;
	}
	
	/**
	 * this method gets the granularity id accordingly to the granularity name
	 * 
	 * @param gr the granularity name
	 * @return the identifier of the granularity used in JavaDateCalendarManager (timebench)
	 */
	private int getId(String gr){
		if( gr.equals("hour") ){
			return JavaDateCalendarManager.Granularities.Hour.toInt();
		}
		if( gr.equals("day") ){
			return JavaDateCalendarManager.Granularities.Day.toInt();
		}
		if( gr.equals("week") ){
			return JavaDateCalendarManager.Granularities.Week.toInt();
		}
		if( gr.equals("month") ){
			return JavaDateCalendarManager.Granularities.Month.toInt();
		}
		if( gr.equals("year") ){
			return JavaDateCalendarManager.Granularities.Year.toInt();
		}
		
		System.out.println( "Granularity in XMLAxesDefinitionReader not supported at the moment!" );
		return -1; // default
	}
}